package com.opd.soeghtool;

import android.util.Log;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import static java.lang.Runtime.getRuntime;

public class ExeCommand {

    private final String TAG ="ADB: ";
    private Process process;
    private BufferedReader successResult;
    private BufferedReader errorResult;
    private DataOutputStream os;
    private boolean bSynchronous;
    private boolean bRunning = false;
    ReadWriteLock lock = new ReentrantReadWriteLock();
    private StringBuffer result = new StringBuffer();
    public ExeCommand(boolean synchronous) {
        bSynchronous = synchronous;
    }
    public ExeCommand() {
        bSynchronous = true;
    }
    public boolean isRunning() {
        return bRunning;
    }
    public String getResult() {
        Lock readLock = lock.readLock();
        readLock.lock();
        try {
            return new String(result);
        } finally {
            readLock.unlock();
        }
    }
    public ExeCommand run(String command, final int maxTime) {
        if (command == null || command.length() == 0) {
            return this;
        }

        try {
            process = getRuntime().exec("sh");//看情况可能是su
        } catch (Exception e) {
            return this;
        }
        bRunning = true;
        successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
        errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
        os = new DataOutputStream(process.getOutputStream());

        try {
            //写入要执行的命令
            os.write(command.getBytes());
            os.writeBytes("\n");
            os.flush();

            os.writeBytes("exit\n");
            os.flush();

            os.close();
            //如果等待时间设置为非正，就不开启超时关闭功能
            if (maxTime > 0) {
                //超时就关闭进程
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(maxTime);
                        } catch (Exception e) {
                        }
                        try {
                            int ret = process.exitValue();
                        } catch (IllegalThreadStateException e) {
                            process.destroy();
                        }
                    }
                }).start();
            }

            //开一个线程来处理input流
            final Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    String line;
                    Lock writeLock = lock.writeLock();
                    try {
                        while ((line = successResult.readLine()) != null) {
                            line += "\n";
                            writeLock.lock();
                            result.append(line);
                            writeLock.unlock();
                        }
                    } catch (Exception e) {
                        Log.i(TAG, e.toString());
                    } finally {
                        try {
                            successResult.close();
                        } catch (Exception e) {
                            Log.i(TAG,  e.toString());
                        }
                    }
                }
            });
            thread.start();

            //开一个线程来处理error流
            final Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    String line;
                    Lock writeLock = lock.writeLock();
                    try {
                        while ((line = errorResult.readLine()) != null) {
                            line += "\n";
                            writeLock.lock();
                            result.append(line);
                            writeLock.unlock();
                        }
                    } catch (Exception e) {
                        Log.i(TAG, e.toString());
                    } finally {
                        try {
                            errorResult.close();
                        } catch (Exception e) {
                            Log.i(TAG, e.toString());
                        }
                    }
                }
            });
            thread2.start();

            Thread thread3 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        //等待执行完毕
                        thread.join();
                        thread2.join();
                        process.waitFor();
                    } catch (Exception e) {

                    } finally {
                        bRunning = false;
                    }
                }
            });
            thread3.start();

            if (bSynchronous) {
                thread3.join();
            }
        } catch (Exception e) {
            Log.i(TAG, e.toString());
        }
        return this;
    }

}
